package com.xqls.server.netty;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * Created by Skeyedu on 2017/3/9.
 */
public class DecoderUtil {
	private static Logger logger = Logger.getLogger(DecoderUtil.class);

	/**
	 * 读取3个字节16进制字符串
	 * 
	 * @return
	 */
	public static String threeToHex(ByteBuf in) {
		return toHex(in,3);
	}

	private  static String toHex(ByteBuf in ,int length){

		try {
			StringBuffer sbf = new StringBuffer();
			for(int i=0;i<length;i++){
				sbf.append(toHex(in.readByte()));
			}
			return sbf.toString();
		} catch (Exception e) {
			logger.error("读取3个字节16进制字符串异常", e);
		}
		return null;

	}

	/**
	 * 读取个字节16进制字符串
	 *
	 * @return
	 */
	public static String fourToHex(ByteBuf in) {
		return toHex(in,4);
	}


	/**
	 * byte写入 固定长度的int
	 * 
	 * @param integer
	 * @param in
	 * @param length
	 */
	public static void integerToBytes(Integer integer, ByteBuf in, int length) {
		double step = Math.pow(10, length - 1);
		Double data = 0d;
		String string;
		for (int i = length; i > 1; i--) {
			data = integer / step;
			step = step / 10;
			string = String.valueOf(integer);
			if (data >= 1 && StringUtils.isNotEmpty(string) && string.length() > 1) {
				integer = Integer.valueOf(String.valueOf(integer).substring(1));
				in.writeByte(intToByte(data.intValue()));
			} else {
				in.writeByte(0);
			}

		}
		in.writeByte(intToByte(integer % 10));

	}

	public static void main(String[] args) {
		ByteBuf buf = Unpooled.buffer(20);
		toBCDDate(new Date(),buf);
         byte[] y=  buf.array();
		System.out.println(toHex(buf,y.length));





	}

	/**
	 * 截取二进制字符串中的单个 bit
	 * 
	 * @param bitStr
	 * @param index
	 * @return
	 */
	public static Integer bitToInteger(String bitStr, int index) {

		return Integer.parseInt(bitStr.charAt(index) + "");

	}

	public static int byteToInt(byte b) {
		// Java 总是把 byte 当做有符处理；我们可以通过将其和 0xFF 进行二进制与得到它的无符值
		return b & 0xFF;
	}

	/**
	 * Byte转Bit
	 */
	public static String byteToBit(byte b) {
		return "" + (byte) ((b >> 7) & 0x1) + (byte) ((b >> 6) & 0x1) + (byte) ((b >> 5) & 0x1)
				+ (byte) ((b >> 4) & 0x1) + (byte) ((b >> 3) & 0x1) + (byte) ((b >> 2) & 0x1) + (byte) ((b >> 1) & 0x1)
				+ (byte) ((b >> 0) & 0x1);
	}

	/**
	 * byte转换16进制字符串
	 * 
	 * @param b
	 * @return
	 */
	public static String toHex(byte b) {
		try {
			String result = Integer.toHexString(b & 0xFF);
			if (result.length() == 1) {
				result = '0' + result;
			}
			return result;
		} catch (Exception e) {
			logger.error("读取16进制字符串异常", e);
		}
		return null;
	}

	/**
	 * 数字字符串转ASCII码字符串
	 *
	 *            字符串
	 * @return ASCII字符串
	 */
	public static String StringToAsciiString(String hex) {
		StringBuilder sb = new StringBuilder();
		StringBuilder temp = new StringBuilder();

		// 49204c6f7665204a617661 split into two characters 49, 20, 4c...
		for (int i = 0; i < hex.length() - 1; i += 2) {

			// grab the hex in pairs
			String output = hex.substring(i, (i + 2));
			// convert hex to decimal
			int decimal = Integer.parseInt(output, 16);
			// convert the decimal to character
			sb.append((char) decimal);

			temp.append(decimal);
		}

		return sb.toString();
	}
	public static String  byteToAscii(ByteBuf in ,int length){

		try {
			StringBuffer sbf = new StringBuffer();
			for(int i=0;i<length;i++){
				sbf.append(StringToAsciiString(toHex(in.readByte())));
			}
			return sbf.toString();
		} catch (Exception e) {
			logger.error("读取3个字节16进制字符串异常", e);
		}
		return null;

	}

	/**
	 * 将short转换为16位int
	 *
	 * @param
	 * @return int
	 */
	public static int shortToInt(short shortValue) {
		return byte2int(shortToBytesLe(shortValue));
	}

	/**
	 * 将长度为2的byte数组转换为16位int
	 *
	 * @param res
	 *            byte[]
	 * @return int
	 */
	public static int byte2int(byte[] res) {
		// res = InversionByte(res);
		// 一个byte数据左移24位变成0x??000000，再右移8位变成0x00??0000
		int targets = (res[0] & 0xff) | ((res[1] << 8) & 0xff00); // | 表示安位或
		return targets;
	}

	/**
	 * short转成 byte数组
	 * 
	 * @param shortValue
	 * @return
	 */
	public static byte[] shortToBytesLe(short shortValue) {
		byte[] bytes = new byte[2];

		for (int i = 0; i < bytes.length; ++i) {
			bytes[i] = (byte) (shortValue >> i * 8 & 0xFF);
		}
		return bytes;
	}

	/**
	 * int转成byte数组
	 * 
	 * @param intValue
	 * @return
	 */
	public static byte[] intToBytesLe(int intValue) {
		byte[] bytes = new byte[4];

		for (int i = 0; i < bytes.length; ++i) {
			bytes[i] = (byte) (intValue >> i * 8 & 0xFF);
		}

		return bytes;
	}

	public static byte intToByte(int x) {
		System.out.println((byte) x);
		return (byte) x;
	}

	public static Date getBCDDate(ByteBuf in) {
		try {
			String secend = toHex(in.readByte());// 秒的bCD码
			String min = toHex(in.readByte());// 分钟的bCD码
			String hour = toHex(in.readByte());// 小时的bCD码
			String day = toHex(in.readByte());// 小时的bCD码
			String mounth = toHex(in.readByte());// 小时的bCD码
			String year = "20" + toHex(in.readByte());// 年的bCD码
			SimpleDateFormat myFmt2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			return myFmt2.parse(year + "-" + mounth + "-" + day + " " + hour + ":" + min + ":" + secend);
		} catch (Exception e) {
			logger.error("读取bcd码时间异常", e);
		}

		return null;
	}



	public static void toBCDDate(Date date, ByteBuf in) { // 10-BCD-16
		try {
			/*
			 * String secend= toHex(in.readByte());//秒的bCD码 String min=
			 * toHex(in.readByte());//分钟的bCD码 String hour=
			 * toHex(in.readByte());//小时的bCD码 String day=
			 * toHex(in.readByte());//小时的bCD码 String mounth=
			 * toHex(in.readByte());//小时的bCD码 String year= "20"+
			 * toHex(in.readByte());//年的bCD码 SimpleDateFormat myFmt2=new
			 * SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			 */
			Calendar cal = Calendar.getInstance();
			cal.setTime(date);
			int year = cal.get(Calendar.YEAR);// 获取年份
			year=year%100;
			int month = cal.get(Calendar.MONTH) + 1;// 获取月份
			int day = cal.get(Calendar.DATE);// 获取日
			int hour = cal.get(Calendar.HOUR_OF_DAY);  // 小时
			int minute = cal.get(Calendar.MINUTE);// 分
			int second = cal.get(Calendar.SECOND);// 秒
			in.writeBytes(hexStringToBytes(binaryString2hexString(str2Bcd(year))));
			in.writeBytes(hexStringToBytes(binaryString2hexString(str2Bcd(month))));
			in.writeBytes(hexStringToBytes(binaryString2hexString(str2Bcd(day))));
			in.writeBytes(hexStringToBytes(binaryString2hexString(str2Bcd(hour))));
			in.writeBytes(hexStringToBytes(binaryString2hexString(str2Bcd(minute))));
			in.writeBytes(hexStringToBytes(binaryString2hexString(str2Bcd(second))));
			//in.writeBytes(intToBytesLe(Integer.valueOf(binaryString2hexString(str2Bcd(year)))));
		} catch (Exception e) {
			logger.error("读取bcd码时间异常", e);
		}

	}

	/**
	 * Convert hex string to byte[]
	 * 
	 * @param hexString
	 *            the hex string
	 * @return byte[]
	 */
	public static byte[] hexStringToBytes(String hexString) {
		if (hexString == null || hexString.equals("")) {
			return null;
		}
		hexString = hexString.toUpperCase();
		int length = hexString.length() / 2;
		char[] hexChars = hexString.toCharArray();
		byte[] d = new byte[length];
		for (int i = 0; i < length; i++) {
			int pos = i * 2;
			d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
		}
		return d;
	}

	/**
	 * Convert char to byte
	 * 
	 * @param c
	 *            char
	 * @return byte
	 */
	private static byte charToByte(char c) {
		return (byte) "0123456789ABCDEF".indexOf(c);
	}

	/**
	 * 数字字符串转8-4-2-1BCD码
	 * 
	 * @param
	 * @return
	 */
	public static String str2Bcd(Integer num) {
		String a = "";
		String asc = num.toString();
		int[] intarry ;
		int  intarryInde=0;
		if(asc.length()==1){  //如果 num的值是 9  需要补成09
			intarryInde=1;
			intarry= new int[asc.length()+1];
		}else{
			intarry = new int[asc.length()];
		}
		for (int i = 0; i < asc.length(); i++) {
			intarry[i+intarryInde] = Integer.parseInt(String.valueOf(asc.charAt(i)));
		}
		for (int i = 0; i < intarry.length; i++) {
			switch (intarry[i]) {
			case 0:
				a = a + "0000";
				break;
			case 1:
				a = a + "0001";
				break;
			case 2:
				a = a + "0010";
				break;
			case 3:
				a = a + "0011";
				break;
			case 4:
				a = a + "0100";
				break;
			case 5:
				a = a + "0101";
				break;
			case 6:
				a = a + "0110";
				break;
			case 7:
				a = a + "0111";
				break;
			case 8:
				a = a + "1000";
				break;
			case 9:
				a = a + "1001";
				break;

			default:
				break;
			}
		}
		return a;
	}

	public static String binaryString2hexString(String bString) {
		if (bString == null || bString.equals(""))
			return null;
		StringBuffer tmp = new StringBuffer();
		int iTmp = 0;
		for (int i = 0; i < bString.length(); i += 4) {
			iTmp = 0;
			for (int j = 0; j < 4; j++) {
				iTmp += Integer.parseInt(bString.substring(i + j, i + j + 1)) << (4 - j - 1);
			}
			tmp.append(Integer.toHexString(iTmp));
		}

		return tmp.toString();
	}

}
